<?
/**
 * 	The data caching class.
 *
 *	@copyright	2010 - oneDot only<br>
 *  You can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.<br>
 *  The content is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose.  see the GNU General Public License for more details.
 *
 *	@author		Koen Betsens <we@onedotonly.be>
 *  @package	Global
 */

/**
 * The data caching class.
 *
 * All external, social or cpu-intensive data is stored in timed entries. Once the lifetime cycle is exceeded, the entries will be updated (and latter ones deleted).    
 *
 * <code>
 * global $CACHE = new CACHE( time, limit );
 * </code>
 *
 * @package		Global
 *
 * @return		Object	DB session
 */
class CACHE{
	
	/**
	 * Default refresh rate
	 * @var	int
	 */
	 public $time = 15;
	 
	 /**
	 * Default store amount
	 * @var	int
	 */
	 public $limit = 24;
	
	/**
	 * Constructs the Cache object
	 *
	 * @param 	int 	$time		Life cycle in minutes. Defaults to 15 min
	 * @param 	int 	$limit		The amount of entries, older entries get deleted. Defaults to 24. Zero ( 0 ) equals "no delete".
	 * @return	object
	 */
 	function __construct( $time = 15, $limit = 24 ){
		
		$this->time		= (int) $time;
		$this->limit	= (int) $limit;

	}
	
	//////////////////// PUBLIC CACHE FUNCTIONS
	
	/**
	 * Bare cache request
	 *
	 * Returns untimed result. For timed cahce results, use the test() function
	 *
	 * @param 	string  $querystring		query string
	 * @param 	int  	$return		return query result
	 * @return	resource	the unfiltered query result, if $return is true
	 */	
	public function filter ( $type, $parentid, $meta = null, $limit = false, $is_array = false ) {
		global $DB;
		
		
		if( $response = $DB->query( "select cache.cache from cache where " . $this->condition( $type, $parentid, $meta, $limit? $limit : $this->limit, 0 )))
			
			while ( $row = mysql_fetch_array( $response, MYSQL_ASSOC))
					if( $row[ "cache" ])
						$cache[] = json_decode( $row[ "cache" ], $is_array );

		return $cache;
	}
	
	
	/**
	
	 */
	public function test ( $type, $parentid, $meta = null, $limit = false, $is_array = false ) {
		global $DB;
		
		
		if( $response = $DB->query( "select cache.cache from cache where " . $this->condition( $type, $parentid, $meta, $limit? $limit : $this->limit, 1 )))
			
			while ( $row = mysql_fetch_array( $response, MYSQL_ASSOC))
					if( $row[ "cache" ])
						$cache[] = json_decode( $row[ "cache" ], $is_array );

		return $cache;
	}


	/**
	
	 */
	public function insert ( $type, $cache, $parentid, $unique, $meta = null ) {
		global $DB;
		
		if( $this->limit < $this->count( $type, $parentid, $meta ))
			$DB->query( "delete from cache where " . $this->condition( $type, $parentid, $meta, $this->limit . ", 1000" ), false );
		
		
		$meta[ "unique" ]	= $unique;

		if( !$this->count( $type, $parentid, $meta ))
			
			 $DB->query( "insert into cache( type, parentid, flog, llog, meta, cache ) values ( " . $DB->type( $type ) . ", $parentid, now(), now(), '" . json_encode( $meta ) . "', '" . json_encode( $cache ) . "' )", false );
		else $DB->query( "update cache set llog = now() where " . $this->condition( $type, $parentid, $meta, 1 ), false );
	}
	
	
	/**
	
	 */
	public function count ( $type, $parentid, $meta = null, $time = false ) {
		global $DB;
		
		if( $response = $DB->query("select count(*) from cache where " . $this->condition( $type, $parentid, $meta, 1000, $time )))
			$row = mysql_fetch_array( $response, MYSQL_ASSOC);


		return (int) $row[ "count(*)" ];

	}
	
	
	/**
	
	 */
	private function condition ( $type, $parentid, $meta = null, $limit = CACHE::limit, $time = null ) {
		global $DB;
		
		if( $time )
			$condt[] = " && time_to_sec( timediff( now(), llog )) <= " . ( $this->time *60 );
		
		if( $meta )
			foreach( $meta as $key => $val )
				
				$condt[] = " && meta regexp '\"$key\":\"?" . str_replace( array("+","?","ˆ","$","|","\\"), ".", $val ) . "\"?'";
			
		
		return "type =" . $DB->type( $type ) . " && parentid = $parentid" . implode( "", $condt ) . " order by flog desc limit $limit";
	}
}

?>